<?php

namespace App\Http\Controllers\Api;

use App\Modules\Common\JewelryRank;
use App\Modules\Common\LowerRank;
use App\Modules\Common\LowerRebateRank;
use App\Modules\Common\LowerSalesRank;
use App\Modules\Common\Models\SystemSwitch;
use App\Modules\Common\MoneyRank;
use App\Modules\Common\NumberRank;
use App\Modules\Common\PartnerJewelryRank;
use App\Modules\Common\PartnerMoneyRank;
use App\Modules\Common\PartnerNumberRank;
use App\Modules\Common\PartnerPhotoRank;
use App\Modules\Common\PartnerRebateRank;
use App\Modules\Common\PhotoRank;
use App\Modules\Common\RebateRank;
use App\Modules\Order\Models\Order;
use App\Modules\Rebate\Models\Rebate;
use App\Modules\Shop\Shop;
use App\Modules\User\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class TeamController extends ApiController
{

    public function getRankingList()
    {
        // 更新redis
        // RebateRank::refresh();
        // JewelryRank::refresh();
        // MoneyRank::refresh();
        // PhotoRank::refresh();
        // NumberRank::refresh();

        // PartnerJewelryRank::refresh();
        // PartnerMoneyRank::refresh();
        // PartnerPhotoRank::refresh();
        // PartnerRebateRank::refresh();
        // PartnerNumberRank::refresh();

        // LowerSalesRank::refresh();
        // LowerRebateRank::refresh();

        $user = $this->getUser();
        if ($user->level != 3) {
            return $this->success([]);
        }
        $switch = SystemSwitch::query()->first();
        $re = [];
        if (is_null($switch)) {
            return $this->success($re);
        }
        if ($switch->rebate_ranking) {
            $re[] = SystemSwitch::$show['rebate_ranking'];
        }
        if ($switch->money_ranking) {
            $re[] = SystemSwitch::$show['money_ranking'];
        }
            
        $re[] = SystemSwitch::$show['shop_ranking'];
        // if ($switch->number_ranking) {
        //     $re[] = SystemSwitch::$show['number_ranking'];
        // }
        // if ($switch->photo_ranking) {
        //     $re[] = SystemSwitch::$show['photo_ranking'];
        // }

        // if ($switch->jewelry_ranking) {
        //     $re[] = SystemSwitch::$show['jewelry_ranking'];
        // }
        return $this->success($re);
    }

    public function getRank(Request $request)
    {
        $user = $this->getUser();
        if ($user->level != 3) {
            return $this->fail('非商家职员');
        }
        $this->validate($request, [
            'type'     => 'required|string',
            'interval' => 'required|string',
            'offset'   => 'required|integer',
            'count'    => 'required|integer',
        ]);
        $interval  = $request->input('interval');
        $type      = $request->input('type');
        $offset    = $request->input('offset');
        $count     = $request->input('count');
        $shop_name = $request->input('shop_name', '');
        $year      = $request->input('year', '');
        $field     = array_search($type, SystemSwitch::$show);
        if (is_null($field)) {
            return $this->success([]);
        }
        $list  = [];
        $self  = 0;
        $score = 0;
        $len   = 0;
        $year  = (int)$year > 0 ? $year : '';
        switch ($field) {
            case 'rebate_ranking':
                RebateRank::setKey($interval.$year);
                $list  = RebateRank::getList($offset, $count);
                $self  = RebateRank::getRank($user->id);
                $score = RebateRank::getScore($user->id);
                $len   = RebateRank::getLength();
                break;
            case 'money_ranking':
                MoneyRank::setKey($interval.$year);
                $list  = MoneyRank::getList($offset, $count);
                $self  = MoneyRank::getRank($user->id);
                $score = MoneyRank::getScore($user->id);
                $len   = MoneyRank::getLength();
                break;
            case 'number_ranking':
                NumberRank::setKey($interval);
                $list  = NumberRank::getList($offset, $count);
                $self  = NumberRank::getRank($user->id);
                $score = NumberRank::getScore($user->id);
                $len   = NumberRank::getLength();
                break;
            case 'photo_ranking':
                PhotoRank::setKey($interval);
                $list  = PhotoRank::getList($offset, $count);
                $self  = PhotoRank::getRank($user->id);
                $score = PhotoRank::getScore($user->id);
                $len   = PhotoRank::getLength();
                break;
            case 'jewelry_ranking':
                JewelryRank::setKey($interval);
                $list  = JewelryRank::getList($offset, $count);
                $self  = JewelryRank::getRank($user->id);
                $score = JewelryRank::getScore($user->id);
                $len   = JewelryRank::getLength();
                break;
            case 'shop_ranking':
                $all   = RebateRank::shop_ranking($offset, $count, $shop_name, $interval, $year);//分页数据
                $list  = isset($all['money_list']) ? $all['money_list'] : [];
                $shops = isset($all['shop_list'])  ? $all['shop_list']  : [];
                $re    = RebateRank::shop_ranking_all($user->id, $shop_name, $interval, $year);
                $self  = $re['self'];//个人排名
                $score = $re['score'];//个人金额
                $len   = $re['len'];//总数
                break;
        }

        $id = array_keys($list);
        $users = User::query()->find($id)->keyBy('id');
        $re = [];
        $re['self'] = [
            'rank' => $score? $self + 1 : $len + 1,
            'score' => $score? $score : 0,
        ];
        foreach ($list as $key => $value) {
            $user = $users->get($key);
            $re['rank'][] = [
                'nickname'  => $user->nickname,
                'name'      => $user->name,
                'avatar'    => $user->avatar,
                'score'     => $value,
                'shop_name' => !empty($shops) ? (!empty($shops[$key]) ? $shops[$key] : '') : '',
            ];
        }
        return $this->success($re);
    }

    public function getPartnerRankingList()
    {
        $user = $this->getUser();
        if ($user->level != 2) {
            return $this->success([]);
        }
        $switch = SystemSwitch::query()->first();
        $re = [];
        if (is_null($switch)) {
            return $this->success($re);
        }
        if ($switch->partner_rebate_ranking) {
            $re[] = SystemSwitch::$show['rebate_ranking'];
        }
        if ($switch->partner_money_ranking) {
            $re[] = SystemSwitch::$show['money_ranking'];
        }

        $re[] = SystemSwitch::$show['shop_ranking'];

        // if ($switch->partner_number_ranking) {
        //     $re[] = SystemSwitch::$show['number_ranking'];
        // }
        // if ($switch->partner_photo_ranking) {
        //     $re[] = SystemSwitch::$show['photo_ranking'];
        // }

        // if ($switch->partner_jewelry_ranking) {
        //     $re[] = SystemSwitch::$show['jewelry_ranking'];
        // }
        return $this->success($re);
    }

    public function getPartnerRank(Request $request)
    {
        $user = $this->getUser();
        if ($user->level != 2) {
            return $this->fail('非合伙人');
        }
        $this->validate($request, [
            'type'     => 'required|string',
            'interval' => 'required|string',
            'offset'   => 'required|integer',
            'count'    => 'required|integer',
        ]);
        $interval  = $request->input('interval');
        $type      = $request->input('type');
        $offset    = $request->input('offset');
        $count     = $request->input('count');
        $shop_name = $request->input('shop_name');
        $field     = array_search($type, SystemSwitch::$show);
        $year      = $request->input('year', '');

        if (is_null($field)) {
            return $this->success([]);
        }
        $list  = [];
        $self  = 0;
        $score = 0;
        $len   = 0;
        $year  = (int)$year > 0 ? $year : '';
        switch ($field) {
            case 'rebate_ranking':
                PartnerRebateRank::setKey($interval.$year);
                $list  = PartnerRebateRank::getList($offset, $count);
                $self  = PartnerRebateRank::getRank($user->id);
                $score = PartnerRebateRank::getScore($user->id);
                $len   = PartnerRebateRank::getLength();
                break;
            case 'money_ranking':
                PartnerMoneyRank::setKey($interval.$year);
                $list  = PartnerMoneyRank::getList($offset, $count);
                $self  = PartnerMoneyRank::getRank($user->id);
                $score = PartnerMoneyRank::getScore($user->id);
                $len   = PartnerMoneyRank::getLength();
                break;
            case 'number_ranking':
                PartnerNumberRank::setKey($interval);
                $list  = PartnerNumberRank::getList($offset, $count);
                $self  = PartnerNumberRank::getRank($user->id);
                $score = PartnerNumberRank::getScore($user->id);
                $len   = PartnerNumberRank::getLength();
                break;
            case 'photo_ranking':
                PartnerPhotoRank::setKey($interval);
                $list  = PartnerPhotoRank::getList($offset, $count);
                $self  = PartnerPhotoRank::getRank($user->id);
                $score = PartnerPhotoRank::getScore($user->id);
                $len   = PartnerPhotoRank::getLength();
                break;
            case 'jewelry_ranking':
                PartnerJewelryRank::setKey($interval);
                $list  = PartnerJewelryRank::getList($offset, $count);
                $self  = PartnerJewelryRank::getRank($user->id);
                $score = PartnerJewelryRank::getScore($user->id);
                $len   = PartnerJewelryRank::getLength();
                break;
            case 'shop_ranking':
                $all   = PartnerRebateRank::shop_ranking($offset, $count, $shop_name, $interval, $year);//分页数据
                $list  = isset($all['money_list']) ? $all['money_list'] : [];
                $shops = isset($all['shop_list'])  ? $all['shop_list']  : [];
                $re    = PartnerRebateRank::shop_ranking_all($user->id, $shop_name, $interval, $year);
                $self  = $re['self'];//个人排名
                $score = $re['score'];//个人金额
                $len   = $re['len'];//总数
                break;
        }
        $id = array_keys($list);
        $users = User::query()->find($id)->keyBy('id');
        $re = [];
        $re['self'] = [
            'rank'  => $score? $self + 1 : $len + 1,
            'score' => $score? $score : 0,
        ];
        foreach ($list as $key => $value) {
            $user = $users->get($key);
            $re['rank'][] = [
                'nickname'  => $user->nickname,
                'name'      => $user->name,
                'avatar'    => $user->avatar,
                'score'     => $value,
                'shop_name' => !empty($shops) ? (!empty($shops[$key]) ? $shops[$key] : '') : '',
            ];
        }
        return $this->success($re);
    }

    public function getStatistics()
    {
        $user = $this->getUser();
        $team = $user->getTeam();
        $data = Order::query()
            ->leftJoin('rebates', 'rebates.link_id', '=', 'orders.id')
            ->whereIn('orders.referrer_id', $team->pluck('id')->all())
            ->where('personal_id', $user->id)
            ->where('orders.referrer_level', 2)
            ->where('rebates.origin', Order::class)
            ->where('orders.status', Order::STATUS_PAID)
            ->selectRaw('sum(rebates.money) as rebate, sum(orders.original_price) as price, count(distinct orders.id) as order_number')
            ->first();
        $re = [
            'money' => $data->price??0,
            'rebate'=> $data->rebate??0,
            'order_number' => $data->order_number??0,
        ];
        return $this->success($re);
    }

    public function getRebate(Request $request)
    {
        $this->validate($request, [
            'offset' => 'nullable|integer',
            'count' => 'nullable|integer',
            'name' => 'nullable|string'
        ]);
        $name = $request->input('name');
        $offset = $request->input('offset', 0);
        $count = $request->input('count', 10);
        $user = $this->getUser();

        $query = User::query()
            ->where('personal_id', $user->id)
            ->where('level', 2);
        if (!empty($name)) {
            $query->where('name', 'like', "%".$name."%");
        }
        $re['total'] = $query->count();
        $team = $query->offset($offset)
            ->limit($count)
            ->get();
        $rebates = Rebate::query()
            ->whereIn('user_id', $team->pluck('id')->all())
            ->selectRaw('sum(money) as money, user_id')
            ->where('level', 2)
            ->groupBy('user_id')
            ->get()
            ->keyBy('user_id');
        $re['data'] = $team->map(function ($item) use ($rebates) {
                $rebate = $rebates->get($item->id);
                return [
                    'id' => $item->id,
                    'nickname' => $item->name??$item->nickname,
                    'user_id' => $item->id,
                    'mobile' => $item->mobile,
                    'avatar' => $item->avatar,
                    'level' => $item->level,
                    'rebate' => $rebate->money?? 0,
                ];
            });
        return $this->success($re);
    }

    public function getLowerRank(Request $request)
    {
        $this->validate($request, [
            'type' => 'required|string',
            'interval' => 'required|string',
            'offset' => 'required|integer',
            'count' => 'required|integer',
        ]);
        $type = $request->input('type');
        $interval = $request->input('interval');
        $offset = $request->input('offset');
        $count = $request->input('count');
        $user = $this->getUser();

        if ($type == 'rebate') {
            LowerRebateRank::setKey($interval.":".$user->id);
            $list = LowerRebateRank::getList($offset, $count);
        } elseif ($type == 'sales_volume') {
            LowerSalesRank::setKey($interval.":".$user->id);
            $list = LowerSalesRank::getList($offset, $count);
        }
        if (empty($list)) {
            return $this->success([]);
        }
        $id = array_keys($list);
        $users = User::query()->find($id)->keyBy('id');
        $re = [];
        foreach ($list as $key => $value) {
            $user = $users->get($key);
            $re[] = [
                'nickname' => $user->nickname,
                'name' => $user->name,
                'avatar' => $user->avatar,
                'score' => $value,
            ];
        }
        return $this->success($re);
    }

    public function getOrder(Request $request)
    {
        $this->validate($request, [
            'offset' => 'nullable|integer',
            'count' => 'nullable|integer',
        ]);
        $offset = $request->input('offset', 0);
        $count = $request->input('count', 10);
        $user = $this->getUser();
        $team = $user->getTeam();
        $order = Order::query()
            ->whereIn('referrer_id', $team->pluck('id')->all())
            ->where('referrer_level', 2)
            ->where('personal_id', $user->id)
            ->where('status', Order::STATUS_PAID)
            ->orderBy('created_at', 'desc')
            ->offset($offset)
            ->limit($count)
            ->get();
        $rebates = Rebate::query()
            ->where('origin', Order::class)
            ->whereIn('link_id', $order->pluck('id')->all())
            ->where('level', 2)
            ->get()
            ->keyBy('link_id');
        $users = User::query()
            ->whereIn('id', array_merge($order->pluck('user_id')->all(), $order->pluck('referrer_id')->all()))
            ->get()
            ->keyBy('id');
        $shops = Shop::query()->find($order->pluck('shop_id')->all())->keyBy('id');
        $re = $order->map(function ($item) use($users, $shops, $rebates) {
            $user = $users->get($item->user_id);
            $referrer = $users->get($item->referrer_id);
            $shop = $shops->get($item->shop_id);
            $rebate = $rebates->get($item->id);
            return [
                'id' => $item->id,
                'nickname' => $user->nickname,
                'order_name' => $item->name,
                'avatar' => $user->avatar,
                'created_at' => $item->created_at,
                'title' => $item->title,
                'shop' => $shop->name??'',
                'referrer' => $referrer->name,
                'price' => $item->original_price,
                'rebate' => is_null($rebate)?0:$rebate->money,
            ];
        });
        return $this->success($re);
    }

    /**
     * 搜索门店
     */
    public function getShopList(Request $request)
    {
        $name  = $request->input('name', '');
        $query = Shop::query()
            ->where('status', Shop::STATUS_OPEN)
            ->orderBy('sort', 'desc');

        if (!is_null($name)) {
            $query->where('name', 'like', "%".$name."%");
        }

        $re = $query->get(['id','name']);
        return $this->success($re);
    }
}
